package com.xk.ucs.modbus.config;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.ip.IpParameters;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Date:2021/1/1
 * 关于重连： 1  发送消息时会框架已经做了捕获异常并重连的操作，使用的仍是RETRIES和TIME_OUT，
 * 发送失败则初始化
 **/
@ConditionalOnProperty(name = "modbus.init",havingValue = "true")
@Configuration
@Slf4j
public class ModbusConfig {
    private  static  final  int RETRIES = 10000;
    private  static  final  int TIME_OUT = 10000; //ms
    private  static  final  int WARNING_PERIOD = 10; //s
    private  volatile  boolean inited = false;

    @Autowired
    ModBusProperties modBusProperties;
    @Bean
    public ModbusMaster getMaster(){
        ModbusFactory modbusFactory  = new ModbusFactory();
        IpParameters params = new IpParameters();
        params.setHost(modBusProperties.getHost());
        params.setPort(modBusProperties.getPort());
        ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, true);
        try {
            tcpMaster.setRetries(RETRIES);
            tcpMaster.setTimeout(TIME_OUT);
            //是否使用modbus
                log.info("tcpMater connecting...");
                printDisconnectWarning();
                tcpMaster.init();// 重试的方法
                inited= true;
                log.info("tcpMaster connected on   ip: {} ,port:{} ",modBusProperties.getHost(),modBusProperties.getPort());

        } catch (ModbusInitException e) {
            log.error("tcpMaster init 异常:{}",e.getMessage());
        }
        return tcpMaster;
    }

    private  void  printDisconnectWarning(){
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(
                () -> {
                    if(inited){
                        scheduledExecutorService.shutdownNow();
                        return;
                    }
                    log.warn("tcpMaster 无法成功连接,请检查配置!!!  ip:{},port:{} ",modBusProperties.getHost(),modBusProperties.getPort());
                },WARNING_PERIOD,WARNING_PERIOD,TimeUnit.SECONDS
        );

    }


}
